package com.littlebee.storychild.common.utils;

/**
 * Created by xuhuixiang on 2017/7/12.
 */

import android.os.Build;
import android.util.Log;

import com.squareup.okhttp.Call;
import com.squareup.okhttp.Callback;
import com.squareup.okhttp.FormEncodingBuilder;
import com.squareup.okhttp.MediaType;
import com.squareup.okhttp.MultipartBuilder;
import com.squareup.okhttp.OkHttpClient;
import com.squareup.okhttp.Request;
import com.squareup.okhttp.Request.Builder;
import com.squareup.okhttp.RequestBody;
import com.squareup.okhttp.Response;
import com.zss.library.utils.LogUtils;

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.multipart.FilePart;
import org.apache.commons.httpclient.methods.multipart.MultipartRequestEntity;
import org.apache.commons.httpclient.methods.multipart.Part;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.FileNameMap;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import okio.Buffer;
import okio.BufferedSink;
import okio.Okio;
import okio.Source;

public class OkHttpUtils {
    private static OkHttpClient mOkHttpClient = new OkHttpClient();
    private static MediaType JSON_TYPE = MediaType.parse("application/json; charset=utf-8");
    private static OkHttpUtils.PostMode mode;
    public static String userAgent;
    public static final MediaType MEDIA_TYPE_JSON = MediaType.parse("application/x-www-form-urlencoded; charset=utf-8");//mdiatype 这个需要和服务端保持一致
    public static final MediaType MEDIA_TYPE_MARKDOWN = MediaType.parse("text/x-markdown; charset=utf-8");//mdiatype 这个需要和服务端保持一致

    public OkHttpUtils() {
    }

    public static OkHttpClient getOkHttpClient() {
        return mOkHttpClient;
    }

    public static void setPostMode(OkHttpUtils.PostMode postMode) {
        mode = postMode;
    }

    public static void init(String userAgent) {
        OkHttpUtils.userAgent = userAgent;
    }

    public static void get(String actionUrl, Map<String, String> paramsMap, final OkHttpUtils.ICallback callback) {
        StringBuilder tempParams = new StringBuilder();
        try {
            //处理参数
            int pos = 0;
            for (String key : paramsMap.keySet()) {
                if (pos > 0) {
                    tempParams.append("&");
                }
                //对参数进行URLEncoder
                tempParams.append(String.format("%s=%s", key, /**URLEncoder.encode(*/paramsMap.get(key)/**, "utf-8")*/));
                pos++;
            }
            //补全请求地址
            String requestUrl = String.format("%s/%s?%s", Constant.HOST, actionUrl, tempParams.toString());
            //创建一个请求
            LogUtils.i("XHX","请求地址："+requestUrl);
            Request request = new Request.Builder().url(requestUrl).build();
            mOkHttpClient.newCall(request).enqueue(new Callback() {
                public void onResponse(Response response) throws IOException {
                    if (response.isSuccessful()) {
                        String result = response.body().string();
                        LogUtils.i("NetWorkUtils", "------后台返回 = " + result);
                        callback.onSuccess(result);
                    } else {
                        callback.onError(response.message());
                    }

                }

                public void onFailure(Request request, IOException e) {
                    e.printStackTrace();
                    callback.onError(e.getMessage());
                }
            });
        } catch (Exception e) {
            Log.e("XHX", e.toString());
        }

    }

    public static void post(String actionUrl, Map<String, String> paramsMap,final OkHttpUtils.ICallback callback){
        try {
//            //处理参数
//            StringBuilder tempParams = new StringBuilder();
//            int pos = 0;
//            for (String key : paramsMap.keySet()) {
//                if (pos > 0) {
//                    tempParams.append("&");
//                }
//                tempParams.append(String.format("%s=%s", key, URLEncoder.encode(paramsMap.get(key), "utf-8")));
//                pos++;
//            }
            FormEncodingBuilder builder = new FormEncodingBuilder();
            for (String key : paramsMap.keySet()) {
                if (!paramsMap.get(key).equals(null)) {
                    builder.add(key, /**URLEncoder.encode(*/paramsMap.get(key)/**,"utf-8")*/);
                }else{
                    builder.add(key, "");
                }
            }
//            //补全请求地址
            String requestUrl = String.format("%s/%s", Constant.HOST, actionUrl);
//            //生成参数
//            String params = tempParams.toString();
            //创建一个请求
            LogUtils.i("XHX","地址："+requestUrl);
            LogUtils.i("XHX","请求参数："+builder.toString());
            Request request = new Request.Builder().url(requestUrl).post(builder.build()).build();
            mOkHttpClient.newCall(request).enqueue(new Callback() {
                public void onResponse(Response response) throws IOException {
                    if (response.isSuccessful()) {
                        String result = response.body().string();
                        LogUtils.i("NetWorkUtils", "------后台返回 = " + result);
                        callback.onSuccess(result);
                    } else {
                        callback.onError(response.message());
                    }

                }

                public void onFailure(Request request, IOException e) {
                    e.printStackTrace();
                    callback.onError(e.getMessage());
                }
            });

        } catch (Exception e) {
            Log.e("XHX", e.toString());
        }
    };

    public static void upload(String url/**, String fileKey*/, File file, Map<String, String> map, final OkHttpUtils.IUploadCallback callback) {
        LogUtils.i("NetWorkUtils", "------请求URL = " + url);
        Request request = buildMultipartFormRequest(url, null, new File[]{file}, map, callback);
        mOkHttpClient.newCall(request).enqueue(new Callback() {
            public void onResponse(Response response) throws IOException {
                LogUtils.i("NetWorkUtils", "-----是否成功 = " + response.isSuccessful());
                if (response.isSuccessful()) {
                    String result = response.body().string();
                    LogUtils.i("NetWorkUtils", "------后台返回 = " + result);
                    callback.onSuccess(result);
                } else {
                    callback.onError(response.message());
                }

            }

            public void onFailure(Request request, IOException e) {
                e.printStackTrace();
                callback.onError(e.getMessage());
            }
        });
    }

    public static void upload(String url, String[] fileKey, File[] file, Map<String, String> map, final OkHttpUtils.IUploadCallback callback) {
        LogUtils.i("NetWorkUtils", "------请求URL = " + url);
        Request request = buildMultipartFormRequest(url, fileKey, file, map, callback);
        mOkHttpClient.newCall(request).enqueue(new Callback() {
            public void onResponse(Response response) throws IOException {
                LogUtils.i("NetWorkUtils", "-----是否成功 = " + response.isSuccessful());
                if (response.isSuccessful()) {
                    String result = response.body().string();
                    LogUtils.i("NetWorkUtils", "------后台返回 = " + result);
                    callback.onSuccess(result);
                } else {
                    callback.onError(response.message());
                }

            }

            public void onFailure(Request request, IOException e) {
                e.printStackTrace();
                callback.onError(e.getMessage());
            }
        });
    }

    public static void uploadNew(final String targetURL/**, String fileKey*/, final File targetFile, final OkHttpUtils.IUploadCallback callback) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                com.zss.library.utils.LogUtils.i("XHX", "XHX上唇:" +targetFile.getAbsolutePath());

                PostMethod filePost = new PostMethod(targetURL);
                com.zss.library.utils.LogUtils.i("XHX", "开始上传文件调用:");

                try {
                    Part[] parts = {new FilePart(targetFile.getName(), targetFile)};
                    filePost.setRequestEntity(new MultipartRequestEntity(parts, filePost.getParams()));
                    HttpClient client = new HttpClient();
                    client.getHttpConnectionManager().getParams().setConnectionTimeout(10000);
                    System.out.println("开始上传文件调用start");
                    com.zss.library.utils.LogUtils.i("XHX", "开始上传文件调用start");

                    int status = client.executeMethod(filePost);
                    System.out.println("开始上传文件调用end");
                    com.zss.library.utils.LogUtils.i("XHX", "开始上传文件调用end");

                    if (status == HttpStatus.SC_OK) {
                        System.out.println("上传成功");
                        // 上传成功
                        ///storage/emulated/0/motherapp/18611697983-201708291209.mp3
                        String [] temp = targetFile.getAbsolutePath().split("/");
                        String urls=Constant.UPLOAD_File_PATH+temp[temp.length-1];
                        com.zss.library.utils.LogUtils.i("XHX", "XHX上唇成功:" + urls);
                        //上传成功后pin
                        callback.onSuccess("{\"result\": {\"rc\":0,\"rd\":\"上传成功\"},\"response\":{\"url\":\""+urls+"\"}}");
                    } else {
                        System.out.println("上传失败");
                        com.zss.library.utils.LogUtils.i("XHX", "XHX上唇失败:" + filePost.getResponseBodyAsString());

                        callback.onError("上传失败");
                        // 上传失败
                    }
                } catch (Exception ex) {
                    ex.printStackTrace();
                } finally {
                    filePost.releaseConnection();
                }
            }
        }).start();



    }
    private static Request buildMultipartFormRequest(String url, String[] fileKeys, File[] files, Map<String, String> map, OkHttpUtils.IUploadCallback callback) {
        if (map == null) {
            map = new HashMap();
        }

        MultipartBuilder builder = (new MultipartBuilder()).type(MultipartBuilder.FORM);

        for (int requestBody = 0; requestBody < files.length; ++requestBody) {
            File entry = files[requestBody];
            LogUtils.i("NetWorkUtils", "------param = " + fileKeys[requestBody] + " = " + entry.getAbsolutePath());
            String fileName = entry.getName();
            MediaType fileType = MediaType.parse(guessMimeType(fileName));
            if (callback != null) {
                builder.addFormDataPart(fileKeys[requestBody], fileName, createCustomRequestBody(requestBody, fileType, entry, callback));
            } else {
                builder.addFormDataPart(fileKeys[requestBody], fileName, RequestBody.create(fileType, entry));
            }
        }

        Iterator var10 = ((Map) map).entrySet().iterator();

        while (var10.hasNext()) {
            Entry var12 = (Entry) var10.next();
            LogUtils.i("NetWorkUtils", "------param = " + (String) var12.getKey() + " = " + (String) var12.getValue());
            builder.addFormDataPart((String) var12.getKey(), (String) var12.getValue());
        }

        RequestBody var11 = builder.build();
        return (new Builder()).removeHeader("User-Agent")/**.addHeader("User-Agent", userAgent)*/.url(url).post(var11).build();
    }

    private static String guessMimeType(String path) {
        FileNameMap fileNameMap = URLConnection.getFileNameMap();
        String contentTypeFor = fileNameMap.getContentTypeFor(path);
        if (contentTypeFor == null) {
            contentTypeFor = "application/octet-stream";
        }

        return contentTypeFor;
    }

    public static RequestBody createCustomRequestBody(final int index, final MediaType contentType, final File file, final OkHttpUtils.IUploadCallback listener) {
        return new RequestBody() {
            public MediaType contentType() {
                return contentType;
            }

            public long contentLength() {
                return file.length();
            }

            public void writeTo(BufferedSink sink) throws IOException {
                try {
                    Source e = Okio.source(file);
                    Buffer buf = new Buffer();
                    Long surplusBytes = Long.valueOf(this.contentLength());

                    long readCount;
                    while ((readCount = e.read(buf, 2048L)) != -1L) {
                        sink.write(buf, readCount);
                        listener.onProgress(index, this.contentLength(), (surplusBytes = Long.valueOf(surplusBytes.longValue() - readCount)).longValue(), surplusBytes.longValue() == 0L);
                    }
                } catch (Exception var7) {
                    var7.printStackTrace();
                }

            }
        };
    }

    private static JSONObject map2JSON(Map<String, String> params) {
        if (params == null) {
            return new JSONObject();
        } else {
            JSONObject res = new JSONObject();
            Set entries = params.entrySet();

            try {
                Iterator var3 = entries.iterator();

                while (var3.hasNext()) {
                    Entry entry = (Entry) var3.next();
                    res.put((String) entry.getKey(), entry.getValue());
                }
            } catch (JSONException var5) {
                ;
            }

            return res;
        }
    }


    public static void download(final String url, final String destFileDir, final OkHttpUtils.IDownloadCallback callback, Object tag) {
        Request request = (new Builder()).url(url).tag(tag).build();
        Call call = mOkHttpClient.newCall(request);
        call.enqueue(new Callback() {
            public void onResponse(Response response) {
                InputStream is = null;
                byte[] buf = new byte[2048];
                boolean len = false;
                FileOutputStream fos = null;

                try {
                    is = response.body().byteStream();
                    long e = response.body().contentLength();
                    File dir = new File(destFileDir);
                    if (!dir.exists()) {
                        dir.mkdirs();
                    }

                    File file = new File(dir, OkHttpUtils.getFileName(url));
                    fos = new FileOutputStream(file);
                    long sum = 0L;

                    int len1;
                    while ((len1 = is.read(buf)) != -1) {
                        fos.write(buf, 0, len1);
                        sum += (long) len1;
                        int progress = (int) ((float) sum * 1.0F / (float) e * 100.0F);
                        callback.onProgress(e, sum, progress);
                    }

                    fos.flush();
                    callback.onSuccess(file.getAbsolutePath());
                } catch (IOException var25) {
                    var25.printStackTrace();
                    callback.onError(var25.getMessage());
                } finally {
                    try {
                        if (is != null) {
                            is.close();
                        }
                    } catch (IOException var24) {
                        ;
                    }

                    try {
                        if (fos != null) {
                            fos.close();
                        }
                    } catch (IOException var23) {
                        ;
                    }

                }

            }

            public void onFailure(Request request, IOException e) {
                e.printStackTrace();
                callback.onError(e.getMessage());
            }
        });
    }

    public static void download(String url, String destFileDir, OkHttpUtils.IDownloadCallback callback) {
        download(url, destFileDir, callback, (Object) null);
    }

    private static String getFileName(String path) {
        int separatorIndex = path.lastIndexOf("/");
        return separatorIndex < 0 ? path : path.substring(separatorIndex + 1, path.length());
    }

    //TODO
    static {
        mode = OkHttpUtils.PostMode.FORM;
        userAgent = "Android";
    }

    public static enum PostMode {
        FORM,
        JSON;

        private PostMode() {
        }
    }

    public interface ICallback {
        void onSuccess(String var1);

        void onError(String var1);
    }

    public interface IUploadCallback {
        void onSuccess(String var1);

        void onProgress(int var1, long var2, long var4, boolean var6);

        void onError(String var1);
    }

    public interface IDownloadCallback {
        void onSuccess(String var1);

        void onProgress(long var1, long var3, int var5);

        void onError(String var1);
    }

    /**
     * 统一为请求添加头信息
     *
     * @return
     */
    public Request.Builder addHeaders() {
        Request.Builder builder = new Request.Builder()
                .addHeader("Connection", "keep-alive")
                .addHeader("platform", "1")
                .addHeader("phoneModel", Build.MODEL)
                .addHeader("systemVersion", Build.VERSION.RELEASE)
                .addHeader("appVersion", "1.0.0");
        return builder;
    }
}